/**
 * 温度图表集成测试脚本
 * 测试温度图表组件与校准API的集成
 */

const API_BASE_URL = 'http://localhost:3000/api'

// 测试数据
const TEST_USER_ID = 68
const TEST_DATE = '2025-09-29'

/**
 * 测试温度校准API
 */
async function testTemperatureCalibrationAPI() {
  console.log('\n=== 测试温度校准API ===')
  
  try {
    // 1. 获取基线信息
    console.log('\n--- 获取基线信息 ---')
    const baselineResponse = await fetch(`${API_BASE_URL}/health/temperature-calibration?userId=${TEST_USER_ID}`)
    const baselineResult = await baselineResponse.json()
    
    console.log('基线响应状态:', baselineResponse.status)
    if (baselineResult.success) {
      console.log('基线数据:')
      console.log(`  基线温度: ${baselineResult.data.baseline_temp}℃`)
      console.log(`  锚定偏移量: ${baselineResult.data.anchor_offset}℃`)
      console.log(`  样本数量: ${baselineResult.data.sample_size}`)
      console.log(`  是否有基线: ${baselineResult.data.has_baseline}`)
      
      return {
        baseline_temp: baselineResult.data.baseline_temp,
        anchor_offset: baselineResult.data.anchor_offset
      }
    } else {
      console.log('获取基线失败:', baselineResult.error)
      return null
    }
    
  } catch (error) {
    console.error('测试温度校准API失败:', error)
    return null
  }
}

/**
 * 测试温度数据API
 */
async function testTemperatureDataAPI() {
  console.log('\n=== 测试温度数据API ===')
  
  try {
    // 构造查询时间范围
    const selectedDateObj = new Date(TEST_DATE)
    const startDate = new Date(selectedDateObj.getFullYear(), selectedDateObj.getMonth(), selectedDateObj.getDate(), 0, 0, 0, 0)
    const endDate = new Date(selectedDateObj.getFullYear(), selectedDateObj.getMonth(), selectedDateObj.getDate() + 1, 0, 0, 0, 0)
    
    console.log(`查询日期: ${TEST_DATE}`)
    console.log(`时间范围: ${startDate.toISOString()} - ${endDate.toISOString()}`)
    
    const response = await fetch(`${API_BASE_URL}/health?userId=${TEST_USER_ID}&dataType=temperature&startDate=${startDate.toISOString()}&endDate=${endDate.toISOString()}`)
    const result = await response.json()
    
    console.log('温度数据响应状态:', response.status)
    if (response.ok) {
      const logs = result.data?.logs || result.logs || []
      console.log(`获取到 ${logs.length} 条温度记录`)
      
      if (logs.length > 0) {
        console.log('第一条记录:', logs[0])
        console.log('最后一条记录:', logs[logs.length - 1])
      }
      
      return logs
    } else {
      console.log('获取温度数据失败:', result.error)
      return []
    }
    
  } catch (error) {
    console.error('测试温度数据API失败:', error)
    return []
  }
}

/**
 * 滑动窗口离群值检测算法（与前端组件保持一致）
 */
function cleanRawData(rawPoints) {
  if (rawPoints.length === 0) return []
  
  // 第一步：基本范围过滤
  const basicFiltered = rawPoints.filter(p => p.raw_temp > 25 && p.raw_temp < 45)
  
  if (basicFiltered.length < 3) return basicFiltered
  
  // 第二步：滑动窗口离群值检测
  const windowSize = Math.min(7, Math.floor(basicFiltered.length / 3)) // 动态窗口大小
  const cleanedPoints = []
  
  for (let i = 0; i < basicFiltered.length; i++) {
    const currentPoint = basicFiltered[i]
    
    // 确定窗口范围
    const windowStart = Math.max(0, i - Math.floor(windowSize / 2))
    const windowEnd = Math.min(basicFiltered.length - 1, i + Math.floor(windowSize / 2))
    
    // 获取窗口内的数据点
    const windowPoints = basicFiltered.slice(windowStart, windowEnd + 1)
    const windowTemps = windowPoints.map(p => p.raw_temp)
    
    // 计算窗口内的统计信息
    const mean = windowTemps.reduce((sum, temp) => sum + temp, 0) / windowTemps.length
    const variance = windowTemps.reduce((sum, temp) => sum + Math.pow(temp - mean, 2), 0) / windowTemps.length
    const stdDev = Math.sqrt(variance)
    
    // 离群值检测：使用2.5个标准差作为阈值
    const threshold = 2.5
    const lowerBound = mean - threshold * stdDev
    const upperBound = mean + threshold * stdDev
    
    // 如果当前点在合理范围内，保留它
    if (currentPoint.raw_temp >= lowerBound && currentPoint.raw_temp <= upperBound) {
      cleanedPoints.push(currentPoint)
    } else {
      console.log(`  过滤离群值: ${currentPoint.raw_temp.toFixed(1)}℃ (范围: ${lowerBound.toFixed(1)}℃ - ${upperBound.toFixed(1)}℃)`)
    }
  }
  
  console.log(`  数据清洗: ${rawPoints.length} → ${basicFiltered.length} → ${cleanedPoints.length}`)
  return cleanedPoints
}

/**
 * 模拟前端温度数据处理（带数据清洗）
 */
function processTemperatureData(logs, calibrationData) {
  console.log('\n=== 模拟前端数据处理 ===')
  
  const temperaturePoints = []
  
  logs.forEach((log, index) => {
    const logData = typeof log.data === 'string' ? JSON.parse(log.data) : log.data
    
    // 处理时间戳
    let timestamp = parseInt(logData.ts) || parseInt(log.timestamp)
    if (timestamp < 10000000000) {
      timestamp = timestamp * 1000
    }
    
    // 检查时间戳有效性
    const minValidTimestamp = new Date('2020-01-01').getTime()
    const maxValidTimestamp = new Date('2070-12-31').getTime()
    
    if (timestamp < minValidTimestamp || timestamp > maxValidTimestamp) {
      return
    }
    
    // 提取温度数据
    const temperatureValue = parseFloat(logData.temperature) || 0
    
    if (temperatureValue > 0) {
      const dataPoint = {
        timestamp,
        temperature: temperatureValue,
        time: new Date(timestamp).toLocaleString('zh-CN')
      }
      
      // 如果有校准数据，计算校准后温度
      if (calibrationData) {
        dataPoint.calibratedTemperature = temperatureValue + calibrationData.anchor_offset
      }
      
      temperaturePoints.push(dataPoint)
    }
  })
  
  const sortedData = temperaturePoints.sort((a, b) => a.timestamp - b.timestamp)
  
  // 如果有校准数据，进行数据清洗
  if (calibrationData && sortedData.length > 0) {
    console.log('\n--- 校准后温度数据清洗 ---')
    
    // 准备校准后温度数据进行清洗
    const calibratedRawPoints = sortedData
      .filter(item => item.calibratedTemperature !== undefined)
      .map(item => ({
        timestamp: item.timestamp,
        raw_temp: item.calibratedTemperature
      }))
    
    // 清洗校准后的温度数据
    const cleanedCalibratedPoints = cleanRawData(calibratedRawPoints)
    const cleanedTimestamps = new Set(cleanedCalibratedPoints.map(p => p.timestamp))
    
    // 更新数据：保留所有原始温度，但只保留清洗后的校准温度
    sortedData.forEach(item => {
      if (!cleanedTimestamps.has(item.timestamp)) {
        item.calibratedTemperature = undefined // 移除被过滤的校准温度
      }
    })
  }
  
  console.log(`\n处理后的数据点: ${sortedData.length}`)
  if (sortedData.length > 0) {
    const validCalibratedCount = sortedData.filter(d => d.calibratedTemperature !== undefined).length
    console.log(`有效校准温度点: ${validCalibratedCount}/${sortedData.length}`)
    
    console.log('第一个数据点:', {
      time: sortedData[0].time,
      deviceTemp: sortedData[0].temperature,
      calibratedTemp: sortedData[0].calibratedTemperature?.toFixed(1) || '已过滤'
    })
    console.log('最后一个数据点:', {
      time: sortedData[sortedData.length - 1].time,
      deviceTemp: sortedData[sortedData.length - 1].temperature,
      calibratedTemp: sortedData[sortedData.length - 1].calibratedTemperature?.toFixed(1) || '已过滤'
    })
  }
  
  return sortedData
}

/**
 * 计算统计信息
 */
function calculateStatistics(temperatureData) {
  console.log('\n=== 计算统计信息 ===')
  
  if (temperatureData.length === 0) {
    console.log('无数据可统计')
    return
  }
  
  // 设备温度统计
  const deviceTemperatures = temperatureData.map(d => d.temperature)
  const avgDeviceTemp = deviceTemperatures.reduce((sum, t) => sum + t, 0) / deviceTemperatures.length
  const minDeviceTemp = Math.min(...deviceTemperatures)
  const maxDeviceTemp = Math.max(...deviceTemperatures)
  
  console.log('设备温度统计:')
  console.log(`  平均温度: ${avgDeviceTemp.toFixed(2)}℃`)
  console.log(`  温度范围: ${minDeviceTemp.toFixed(1)}℃ - ${maxDeviceTemp.toFixed(1)}℃`)
  
  // 校准后温度统计（清洗后的数据）
  const calibratedTemperatures = temperatureData
    .filter(d => d.calibratedTemperature !== undefined)
    .map(d => d.calibratedTemperature)
  
  if (calibratedTemperatures.length > 0) {
    const avgCalibratedTemp = calibratedTemperatures.reduce((sum, t) => sum + t, 0) / calibratedTemperatures.length
    const minCalibratedTemp = Math.min(...calibratedTemperatures)
    const maxCalibratedTemp = Math.max(...calibratedTemperatures)
    
    // 数据质量信息
    const originalCount = temperatureData.length
    const cleanedCount = calibratedTemperatures.length
    const filterRate = ((originalCount - cleanedCount) / originalCount * 100).toFixed(1)
    
    console.log('校准后温度统计（清洗后）:')
    console.log(`  数据质量: ${cleanedCount}/${originalCount} (过滤了${filterRate}%的离群值)`)
    console.log(`  平均温度: ${avgCalibratedTemp.toFixed(2)}℃`)
    console.log(`  温度范围: ${minCalibratedTemp.toFixed(1)}℃ - ${maxCalibratedTemp.toFixed(1)}℃`)
    
    // 评估温度状态（基于正常体温范围36.1-37.2℃）
    const normalCount = calibratedTemperatures.filter(t => t >= 36.1 && t <= 37.2).length
    const lowCount = calibratedTemperatures.filter(t => t < 36.1).length
    const highCount = calibratedTemperatures.filter(t => t > 37.2).length
    
    let tempStatus = '正常'
    if (lowCount > normalCount && lowCount > highCount) {
      tempStatus = '偏低'
    } else if (highCount > normalCount && highCount > lowCount) {
      tempStatus = '偏高'
    }
    
    console.log(`  温度状态: ${tempStatus}`)
    console.log(`  正常范围内: ${normalCount}/${calibratedTemperatures.length} (${(normalCount/calibratedTemperatures.length*100).toFixed(1)}%)`)
    
    if (filterRate > 0) {
      console.log(`  ✅ 数据清洗有效：过滤了${originalCount - cleanedCount}个离群值`)
    }
  } else {
    console.log('校准后温度统计: 无有效校准数据（可能全部被过滤）')
  }
}

/**
 * 主测试函数
 */
async function main() {
  console.log('开始测试温度图表集成功能...')
  console.log('测试用户ID:', TEST_USER_ID)
  console.log('测试日期:', TEST_DATE)
  console.log('模拟前端温度图表组件的数据获取和处理流程')
  
  // 1. 获取校准数据
  const calibrationData = await testTemperatureCalibrationAPI()
  
  // 2. 获取温度数据
  const temperatureLogs = await testTemperatureDataAPI()
  
  // 3. 处理温度数据（模拟前端组件逻辑）
  const processedData = processTemperatureData(temperatureLogs, calibrationData)
  
  // 4. 计算统计信息
  calculateStatistics(processedData)
  
  console.log('\n✅ 测试完成!')
  console.log('\n💡 前端集成要点:')
  console.log('- 先获取校准数据，再获取温度数据')
  console.log('- 使用锚定偏移量计算校准后温度')
  console.log('- 使用滑动窗口算法过滤校准后温度的离群值')
  console.log('- 在图表中同时显示设备温度和清洗后的校准温度')
  console.log('- 基于清洗后的校准温度评估健康状态')
  console.log('- 统计信息显示数据清洗的效果和质量')
}

// 运行测试
if (require.main === module) {
  main().catch(console.error)
}

module.exports = {
  testTemperatureCalibrationAPI,
  testTemperatureDataAPI,
  processTemperatureData,
  calculateStatistics
}
